home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 11 / CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso / cucd / graphics / mpimage / si / scalempi.c < prev    next >
C/C++ Source or Header  |  1997-02-16  |  41KB  |  2,042 lines

  1. // MPImage - Amiga Image Conversion
  2. // Copyright (C) © 1996 Mark John Paddock
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mark@topic.demon.co.uk
  19. // mpaddock@cix.compulink.co.uk
  20.  
  21. #include "mpimage.h"
  22.  
  23. BOOL __asm __saveds RescaleMPImage(register __a0 struct MPImage *MPi,register __d0 UWORD x,
  24.                                                 register __d1 UWORD y);
  25.  
  26. static void RescaleXY(UBYTE *in,UWORD w,UWORD h,UBYTE *out,UWORD x,UWORD y,UBYTE *temp);
  27. static void SmoothX(UBYTE *in,UBYTE *out,UWORD w,UWORD x,UWORD y);
  28. static void SmoothY(UBYTE *in,UBYTE *out,UWORD h,UWORD x,UWORD y);
  29. static void SmoothXY(UBYTE *in,UBYTE *out,UWORD w,UWORD h,UWORD x,UWORD y);
  30. static void RescaleXYRGB(UBYTE *inr,UBYTE *ing,UBYTE *inb,UWORD w,UWORD h,UBYTE *outr,UBYTE *outg,UBYTE *outb,
  31.             UWORD x,UWORD y,UBYTE *tr,UBYTE *tg,UBYTE *tb);
  32.  
  33. /****** MPImage.library/RescaleMPImage **************************************
  34. *
  35. *   NAME   
  36. *  RescaleMPImage -- Scales an image created by LoadMPImage() (V3)
  37. *
  38. *   SYNOPSIS
  39. *  error = RescaleMPImage(MPi, x, y)
  40. *  D0                     A0   D0 D1
  41. *
  42. *  BOOL RescaleMPImage(struct MPImage *, UWORD, UWORD);
  43. *
  44. *   FUNCTION
  45. *  Scales an Image loaded by LoadMPImage() to new width and height.
  46. *
  47. *   INPUTS
  48. *  MPi - Image loaded by LoadMPImage
  49. *  x   - New width of image
  50. *  y   - New height of image
  51. *
  52. *   RESULT
  53. *  error - 1 for success, 0 for failure.
  54. *          Use MPImageErrorMessage() to get error.
  55. *
  56. *   EXAMPLE
  57. *
  58. *   NOTES
  59. *  Rescaling of bitmaps is done using BitMapScale().
  60. *  Other rescaling is done using custom code with smoothing.
  61. *
  62. *  If this function fails then the MPImage is no longer usable and
  63. *  FreeMPImage() should be called to free it.
  64. *
  65. *  Version 4.3 is faster for RGB.
  66. *
  67. *   BUGS
  68. *  Bitmaps may not scale smoothly.
  69. *  The rescaling of EGS images is not efficent.
  70. *
  71. *   SEE ALSO
  72. *  LoadMPImage(),MPImageErrorMessage(),FreeMPImage(),
  73. *  graphics.library/BitMapScale().
  74. *
  75. *****************************************************************************
  76. *
  77. */
  78. BOOL __asm __saveds
  79. RescaleMPImage(register __a0 struct MPImage *MPi,register __d0 UWORD x,
  80.                                                 register __d1 UWORD y) {
  81.     UBYTE *msg;
  82.     if (!SetupScreen()) {
  83.         OpenProgressWindow();
  84.     }
  85.     if (MPi->BitMap) {
  86.         // Normal BitMap
  87.         struct BitMap *bitmap;
  88.         if (!(bitmap = AllocBitMap(x,y, MPi->BitMap->Depth,BMF_DISPLAYABLE,MPi->BitMap))) {
  89.             msg = GetMg(MSG_ERR_ALLOCBIT);
  90.         }
  91.         else {
  92.             struct BitScaleArgs BitScaleArgs;
  93.             AddMessageNo(MSG_SCALE);
  94.             BitScaleArgs.bsa_SrcX             = 0;
  95.             BitScaleArgs.bsa_SrcY             = 0;
  96.             BitScaleArgs.bsa_SrcWidth         = MPi->Width;
  97.             BitScaleArgs.bsa_SrcHeight     = MPi->Height;
  98.             BitScaleArgs.bsa_DestX             = 0;
  99.             BitScaleArgs.bsa_DestY             = 0;
  100.             BitScaleArgs.bsa_DestWidth     = x;
  101.             BitScaleArgs.bsa_DestHeight    = y;
  102.             BitScaleArgs.bsa_XSrcFactor    = MPi->Width;
  103.             BitScaleArgs.bsa_XDestFactor    = x;
  104.             BitScaleArgs.bsa_YSrcFactor     = MPi->Height;
  105.             BitScaleArgs.bsa_YDestFactor    = y;
  106.             BitScaleArgs.bsa_SrcBitMap     = MPi->BitMap;
  107.             BitScaleArgs.bsa_DestBitMap    = bitmap;
  108.             BitScaleArgs.bsa_Flags         = 0;
  109.             BitMapScale(&BitScaleArgs);
  110.             if (MPi->Object) {    // Dispose object (frees bit map as well...)
  111.                 DisposeDTObject(MPi->Object);
  112.                 MPi->Object = NULL;
  113.             }
  114.             else {
  115.                 FreeBitMap(MPi->BitMap);
  116.             }
  117.             MPi->BitMap = bitmap;
  118.             MPi->Width = x;
  119.             MPi->Height = y;
  120.             CloseProgressWindow();
  121.             CloseDownScreen();
  122.             return TRUE;
  123.         }
  124.     }
  125.     else {
  126.         if (MPi->EGS_BitMap) {
  127.             // EGS BitMap
  128.             UBYTE *red,*green=NULL,*blue=NULL,*plane;
  129.             UBYTE *r,*g=NULL,*b=NULL,*t=NULL,*t1,*t2;
  130.             UBYTE *rr,*gg,*bb;
  131.             UWORD i,j;
  132.             AddMessageNo(MSG_SCALEE);
  133.             if (!(EGSBase = OpenLibrary((char *)"egs.library",0))) {
  134.                 msg = GetMg(MSG_ERR_EGSL);
  135.                 strcpy(ErrorMessage,msg);
  136.                 CloseProgressWindow();
  137.                 CloseDownScreen();
  138.                 return FALSE;
  139.             }
  140.             if ((red = AllocVec((int)MPi->Width*MPi->Height,0)) &&
  141.                 (green = AllocVec((int)MPi->Width*MPi->Height,0)) &&
  142.                 (blue = AllocVec((int)MPi->Width*MPi->Height,0))) {
  143.                 plane = ((struct E_EBitMapFull *)(MPi->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  144.                 rr = red;
  145.                 gg = green;
  146.                 bb = blue;
  147.                 AddMessageNo(MSG_E2C);
  148.                 SetMax(MPi->Height);
  149.                 for (i = 0; i<MPi->Height; i++) {
  150.                     SetCur(i);
  151.                     for (j = 0; j<MPi->Width; j++) {
  152.                         *rr++ = *plane++;
  153.                         *gg++ = *plane++;
  154.                         *bb++ = *plane++;
  155.                         plane++;
  156.                     }
  157.                     plane += (MPi->EGS_BitMap->BytesPerRow - (4*MPi->Width));
  158.                 }
  159.                 E_DisposeBitMap(MPi->EGS_BitMap);
  160.                 MPi->EGS_BitMap = NULL;
  161.                 if ((r = AllocVec((int)x*y,0)) &&
  162.                     (g = AllocVec((int)x*y,0)) &&
  163.                     (b = AllocVec((int)x*y,0)) &&
  164.                     (t = AllocVec((int)x*y,0))) {
  165.                    AddMessageNo(MSG_SCALER);
  166.                    if ((t1 = AllocVec((int)x*y,0)) &&
  167.                          (t2 = AllocVec((int)x*y,0))) {
  168.                         RescaleXYRGB(red,green,blue,MPi->Width,MPi->Height,r,g,b,x,y,t,t1,t2);
  169.                         FreeVec(t1);
  170.                         FreeVec(t2);
  171.                     }
  172.                     else {
  173.                         if (t1) {
  174.                             FreeVec(t1);
  175.                         }
  176.                         RescaleXY(red,MPi->Width,MPi->Height,r,x,y,t);
  177.                         RescaleXY(green,MPi->Width,MPi->Height,g,x,y,t);
  178.                         RescaleXY(blue,MPi->Width,MPi->Height,b,x,y,t);
  179.                     }
  180.                     FreeVec(red);
  181.                     red = NULL;
  182.                     FreeVec(green);
  183.                     green = NULL;
  184.                     FreeVec(blue);
  185.                     blue = NULL;
  186.                     if (MPi->EGS_BitMap = E_AllocBitMap(x,y,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  187.                         plane = ((struct E_EBitMapFull *)(MPi->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  188.                         rr = r;
  189.                         gg = g;
  190.                         bb = b;
  191.                         AddMessageNo(MSG_2E);
  192.                         SetMax(y);
  193.                         for (i = 0; i<y; i++) {
  194.                             SetCur(i);
  195.                             for (j = 0; j<x; j++) {
  196.                                 *plane++ = *rr++;
  197.                                 *plane++ = *gg++;
  198.                                 *plane++ = *bb++;
  199.                                 plane++;
  200.                             }
  201.                             plane += (MPi->EGS_BitMap->BytesPerRow - (4*x));
  202.                         }
  203.                         MPi->Width = x;
  204.                         MPi->Height = y;
  205.                         FreeVec(r);
  206.                         FreeVec(g);
  207.                         FreeVec(b);
  208.                         FreeVec(t);
  209.                         CloseProgressWindow();
  210.                         CloseDownScreen();
  211.                         return TRUE;
  212.                     }
  213.                     else {    // E_AllocBitMap
  214.                         msg = GetMg(MSG_ERR_ALLOCE);
  215.                     }
  216.                 }
  217.                 else {    // AllocVec red,green,blue
  218.                     msg = GetMg(MSG_ERR_NOMEM);
  219.                 }
  220.                 if (r) FreeVec(r);
  221.                 if (g) FreeVec(g);
  222.                 if (b) FreeVec(b);
  223.                 if (t) FreeVec(t);
  224.             }
  225.             else {    // AllocVec red,green,blue
  226.                 msg = GetMg(MSG_ERR_NOMEM);
  227.             }
  228.             if (red) FreeVec(red);
  229.             if (green) FreeVec(green);
  230.             if (blue) FreeVec(blue);
  231.             CloseLibrary(EGSBase);
  232.         }
  233.         else {
  234.             // RGB || Grey
  235.             if (MPi->GreyScale) {
  236.                 UBYTE *red,*t;
  237.                 if ((red = AllocVec((int)x*y,0)) &&
  238.                      (t = AllocVec((int)x*y,0))) {
  239.                     AddMessageNo(MSG_SCALEG);
  240.                     RescaleXY(MPi->Red,MPi->Width,MPi->Height,red,x,y,t);
  241.                     FreeVec(MPi->Red);
  242.                     FreeVec(t);
  243.                     MPi->Width = x;
  244.                     MPi->Height = y;
  245.                     MPi->Red = red;
  246.                     MPi->Green = red;
  247.                     MPi->Blue = red;
  248.                     CloseProgressWindow();
  249.                     CloseDownScreen();
  250.                     return TRUE;
  251.                 }
  252.                 else {    // AllocVec red,green,blue
  253.                     msg = GetMg(MSG_ERR_NOMEM);
  254.                     if (red) {
  255.                         FreeVec(red);
  256.                     }
  257.                 }
  258.             }
  259.             else {
  260.                 UBYTE *red,*green=NULL,*blue=NULL,*t,*t1,*t2;
  261.                 if ((red = AllocVec((int)x*y,0)) &&
  262.                     (green = AllocVec((int)x*y,0)) &&
  263.                     (blue = AllocVec((int)x*y,0)) &&
  264.                     (t = AllocVec((int)x*y,0))) {
  265.                    AddMessageNo(MSG_SCALER);
  266.                    if ((t1 = AllocVec((int)x*y,0)) &&
  267.                          (t2 = AllocVec((int)x*y,0))) {
  268.                         RescaleXYRGB(MPi->Red,MPi->Green,MPi->Blue,MPi->Width,MPi->Height,red,green,blue,x,y,t,t1,t2);
  269.                         FreeVec(t1);
  270.                         FreeVec(t2);
  271.                     }
  272.                     else {
  273.                         if (t1) {
  274.                             FreeVec(t1);
  275.                         }
  276.                         RescaleXY(MPi->Red,MPi->Width,MPi->Height,red,x,y,t);
  277.                         RescaleXY(MPi->Green,MPi->Width,MPi->Height,green,x,y,t);
  278.                         RescaleXY(MPi->Blue,MPi->Width,MPi->Height,blue,x,y,t);
  279.                     }
  280.                     FreeVec(MPi->Red);
  281.                     FreeVec(MPi->Green);
  282.                     FreeVec(MPi->Blue);
  283.                     FreeVec(t);
  284.                     MPi->Width = x;
  285.                     MPi->Height = y;
  286.                     MPi->Red = red;
  287.                     MPi->Green = green;
  288.                     MPi->Blue = blue;
  289.                     CloseProgressWindow();
  290.                     CloseDownScreen();
  291.                     return TRUE;
  292.                 }
  293.                 else {    // AllocVec red,green,blue
  294.                     msg = GetMg(MSG_ERR_NOMEM);
  295.                 }
  296.                 if (red) FreeVec(red);
  297.                 if (green) FreeVec(green);
  298.                 if (blue) FreeVec(blue);
  299.             }
  300.         }
  301.     }
  302.     strcpy(ErrorMessage,msg);
  303.     CloseProgressWindow();
  304.     CloseDownScreen();
  305.     return FALSE;
  306. }
  307.  
  308. /****** MPImage.library/MPScaleGrey ***************************************
  309. *
  310. *   NAME   
  311. *  MPScaleGrey -- Scales a GreyScale image (V7)
  312. *
  313. *   SYNOPSIS
  314. *  MPScaleGrey( Old,New,OWidth,OHeight,NWidth,NHeight,Temp)
  315. *               A0  A1  D0     D1      D2     D3      A2
  316. *
  317. *  void MPScaleGrey
  318. *           ( UBYTE *,UBYTE *,UWORD,UWORD,UWORD,UWORD,UBYTE *);
  319. *
  320. *   FUNCTION
  321. *  Scales an RGB image.
  322. *
  323. *   INPUTS
  324. *  Old      - Contains existing chunky pixels.
  325. *  New      - Buffer for the new chunky pixels.
  326. *  OWidth   - Current Width.
  327. *  OHeight  - Current Height.
  328. *  NWidth   - New Width.
  329. *  NHeight  - New Height.
  330. *  Temp     - Temporary buffer sized for the new image.
  331. *
  332. *   RESULT
  333. *  The data pointed to by New is updated to the scaled image.
  334. *
  335. *   EXAMPLE
  336. *
  337. *   NOTES
  338. *
  339. *   BUGS
  340. *  Not tested.
  341. *
  342. *   SEE ALSO
  343. *  MPScaleRGB().
  344. *
  345. *****************************************************************************
  346. *
  347. */
  348.  
  349. void __asm __saveds
  350. MPScaleGrey(register __a0 UBYTE *Old,register __a1 UBYTE *New,
  351.                 register __d0 UWORD OWidth,register __d1 UWORD OHeight,
  352.                 register __d2 UWORD NWidth,register __d3 UWORD NHeight,
  353.                 register __a2 UBYTE *Temp) {
  354.     RescaleXY(Old,OWidth,OHeight,
  355.                 New,NWidth,NHeight,Temp);
  356. }
  357.  
  358. /* in = chunky in
  359.  * w  = old width
  360.  * h  = old height
  361.  * out= chunky out
  362.  * x  = new width
  363.  * y  = new height
  364.  * t  = Temp buffer
  365.  */
  366. static void
  367. RescaleXY(UBYTE *in,UWORD w,UWORD h,UBYTE *out,UWORD x,UWORD y,UBYTE *t) {
  368.     float xfact,yfact;
  369.  
  370.     xfact = ((float)w)/x;
  371.     yfact = ((float)h)/y;
  372.  
  373.     if (x == w) {
  374.         if (y == h) {
  375.             AddMessageNo(MSG_COPY);
  376.             memcpy(out,in,w*h);
  377.             return;
  378.         }
  379.         if (y < h) {
  380.             // x == w, y < h
  381.             UWORD j;
  382.             UBYTE *op = out;
  383.             float tf=0.0, bf;
  384.             float yf = 0.0;
  385.             UWORD ys=0,ye;
  386.  
  387.             AddMessageNo(MSG_SLTY);
  388.             SetMax(y);
  389.             for (j=0; j<y; j++) {
  390.                 UWORD i;
  391.                 UBYTE *tin;
  392.  
  393.                 SetCur(j);
  394.                 yf += yfact;
  395.                 ye = (UWORD)yf;
  396.                 bf = yf - ye;
  397.                 if (ys > 0) {
  398.                     tin = in + ((ys-1) * w);
  399.                 }
  400.                 else {
  401.                     tin = in + (ys * w);
  402.                 }
  403.  
  404.                 for (i=0; i<x; i++) {
  405.                     float newf=0.0;
  406.                     UWORD l;
  407.                     UBYTE *tint = tin;
  408.  
  409.                     if (ys > 0) {
  410.                         newf += tint[i] * tf;
  411.                         tint += w;
  412.                     }
  413.                     for (l = ys; l < ye; l++) {
  414.                         newf += tint[i];
  415.                         tint += w;
  416.                     }
  417.                     if (ye < h) {
  418.                         newf += tint[i] * bf;
  419.                     }
  420.                     *op++ = newf/yfact;
  421.                 }
  422.                 ys = ye + 1;
  423.                 tf = ys - yf;
  424.             }
  425.             return;
  426.         }
  427.         {
  428.             // x == w, y > h
  429.             UWORD j;
  430.             UWORD ys=0,ye;
  431.             float yf=0.0;
  432.             UBYTE *op = t;
  433.             UBYTE *tin;
  434.             UWORD i;
  435.  
  436.             AddMessageNo(MSG_SGTY);
  437.             SetMax(y);
  438.             for (j=1; j<y; j++) {
  439.  
  440.                 SetCur(j);
  441.                 yf += yfact;
  442.                 ye = (UWORD)yf;
  443.                 tin = in + (ys * w);
  444.  
  445.                 if (ys == ye) {
  446.                     for (i=0; i<x; i++) {
  447.                         *op++ = *tin++;
  448.                     }
  449.                 }
  450.                 else {
  451.                     float tf,bf;
  452.  
  453.                     bf = yf - floor(yf);
  454.                     tf = yfact - bf;
  455.                     for (i=0; i<x; i++) {
  456.                         *op++ = ((*tin * tf) + (tin[w] * bf)) / yfact;
  457.                         tin++;
  458.                     }
  459.                     ys = ye;
  460.                 }
  461.             }
  462.             tin = in + ((h-1) * w);
  463.             for (i=0; i<x; i++) {
  464.                 *op++ = *tin++;
  465.             }
  466.             SmoothY(t,out,h,x,y);
  467.             return;
  468.         }
  469.     }
  470.     // x != w
  471.     if (x < w) {
  472.         // x < w
  473.         if (y == h) {
  474.             // x < w, y == h
  475.             UWORD j;
  476.             UBYTE *op = out;
  477.             UBYTE *tin = in;
  478.  
  479.             AddMessageNo(MSG_SLTX);
  480.             SetMax(y);
  481.             for (j=0; j<y; j++) {
  482.                 float xf = 0.0;
  483.                 float lf=0.0,rf;
  484.                 UWORD xs=0,xe;
  485.                 UWORD i;
  486.  
  487.                 SetCur(j);
  488.                 for (i=0; i<x; i++) {
  489.                     float newf=0.0;
  490.                     UWORD k;
  491.  
  492.                     xf += xfact;
  493.                     xe = (UWORD)xf;
  494.                     rf = xf - xe;
  495.  
  496.                     if (xs > 0) {
  497.                         newf += tin[xs-1] * lf;
  498.                     }
  499.                     for (k = xs; k < xe; k++) {
  500.                         newf += tin[k];
  501.                     }
  502.                     if (xe < w) {
  503.                         newf += tin[xe] * rf;
  504.                     }
  505.                     *op++ = newf/xfact;
  506.                     xs = xe + 1;
  507.                     lf = xs - xf;
  508.                 }
  509.                 tin += w;
  510.             }
  511.             return;
  512.         }
  513.         if (y < h) {
  514.             // x < w, y < h
  515.             UWORD j;
  516.             float divf;
  517.             UBYTE *op = out;
  518.             float tf=0.0, bf;
  519.             float yf = 0.0;
  520.             UWORD ys=0,ye;
  521.  
  522.             divf = xfact * yfact;
  523.  
  524.             AddMessageNo(MSG_SLTXLTY);
  525.             SetMax(y);
  526.             for (j=0; j<y; j++) {
  527.                 float xf = 0.0;
  528.                 float lf=0.0,rf;
  529.                 UWORD xs=0,xe;
  530.                 UWORD i;
  531.  
  532.                 SetCur(j);
  533.                 yf += yfact;
  534.                 ye = (UWORD)yf;
  535.                 bf = yf - ye;
  536.  
  537.                 for (i=0; i<x; i++) {
  538.                     float newf=0.0;
  539.                     UBYTE *tin;
  540.                     UWORD l;
  541.  
  542.                     xf += xfact;
  543.                     xe = (UWORD)xf;
  544.                     rf = xf - xe;
  545.  
  546.                     if (ys > 0) {
  547.                         UWORD k;
  548.                         tin = in + ((ys-1) * w);
  549.                         if (xs > 0) {
  550.                             newf += tin[xs-1] * lf * tf;
  551.                         }
  552.                         for (k = xs; k < xe; k++) {
  553.                             newf += tin[k] * tf;
  554.                         }
  555.                         if (xe < w) {
  556.                             newf += tin[xe] * rf * tf;
  557.                         }
  558.                         tin += w;
  559.                     }
  560.                     else {
  561.                         tin = in + (ys * w);
  562.                     }
  563.                     for (l = ys; l < ye; l++) {
  564.                         UWORD k;
  565.                         if (xs > 0) {
  566.                             newf += tin[xs-1] * lf;
  567.                         }
  568.                         for (k = xs; k < xe; k++) {
  569.                             newf += tin[k];
  570.                         }
  571.                         if (xe < w) {
  572.                             newf += tin[xe] * rf;
  573.                         }
  574.                         tin += w;
  575.                     }
  576.                     if (ye < h) {
  577.                         UWORD k;
  578.                         newf += tin[xs-1] * lf * bf;
  579.                         for (k = xs; k < xe; k++) {
  580.                             newf += tin[k] * bf;
  581.                         }
  582.                         if (xe < w) {
  583.                             newf += tin[xe] * rf * bf;
  584.                         }
  585.                     }
  586.                     *op++ = newf/divf;
  587.                     xs = xe + 1;
  588.                     lf = xs - xf;
  589.                 }
  590.                 ys = ye + 1;
  591.                 tf = ys - yf;
  592.             }
  593.             return;
  594.         }
  595.         {
  596.             // x < w, y > h
  597.             UWORD j;
  598.             UWORD ys=0,ye;
  599.             float yf=0.0;
  600.             UBYTE *op = t;
  601.             UBYTE *tin;
  602.             UWORD i;
  603.             float divf = xfact * yfact;
  604.             UWORD xs,xe;
  605.             float xf;
  606.             float lf,rf;
  607.  
  608.             AddMessageNo(MSG_SLTXGTY);
  609.             SetMax(y);
  610.             for (j=1; j<y; j++) {
  611.  
  612.                 SetCur(j);
  613.                 xf = 0.0;
  614.                 lf = 0.0;
  615.                 xs = 0;
  616.                 yf += yfact;
  617.                 ye = (UWORD)yf;
  618.                 tin = in + (ys * w);
  619.  
  620.                 if (ys == ye) {
  621.                     for (i=0; i<x; i++) {
  622.                         float newf=0.0;
  623.                         UWORD k;
  624.  
  625.                         xf += xfact;
  626.                         xe = (UWORD)xf;
  627.                         rf = xf - xe;
  628.  
  629.                         if (xs > 0) {
  630.                             newf += tin[xs-1] * lf;
  631.                         }
  632.                         for (k = xs; k < xe; k++) {
  633.                             newf += tin[k];
  634.                         }
  635.                         if (xe < w) {
  636.                             newf += tin[xe] * rf;
  637.                         }
  638.                         *op++ = newf/xfact;
  639.                         xs = xe + 1;
  640.                         lf = xs - xf;
  641.                     }
  642.                 }
  643.                 else {
  644.                     float tf,bf;
  645.                     UWORD k;
  646.  
  647.                     bf = yf - floor(yf);
  648.                     tf = yfact - bf;
  649.  
  650.                     for (i=0; i<x; i++) {
  651.                         float newf=0.0;
  652.  
  653.                         xf += xfact;
  654.                         xe = (UWORD)xf;
  655.                         rf = xf - xe;
  656.  
  657.                         if (xs > 0) {
  658.                             newf += ((tin[xs-1] * tf) + (tin[xs-1+w] * bf)) * lf;
  659.                         }
  660.                         for (k = xs; k < xe; k++) {
  661.                             newf += (tin[k] * tf) + (tin[k+w] * bf);
  662.                         }
  663.                         if (xe < w) {
  664.                             newf += ((tin[xe] * tf) + (tin[xe+w] * bf)) * rf;
  665.                         }
  666.                         *op++ = newf/divf;
  667.                         xs = xe + 1;
  668.                         lf = xs - xf;
  669.                     }
  670.                     ys = ye;
  671.                 }
  672.             }
  673.             tin = in + ((h-1) * w);
  674.             xs = 0;
  675.             lf = 0.0;
  676.             xf = 0.0;
  677.             for (i=0; i<x; i++) {
  678.                 float newf=0.0;
  679.                 UWORD k;
  680.  
  681.                 xf += xfact;
  682.                 xe = (UWORD)xf;
  683.                 rf = xf - xe;
  684.  
  685.                 if (xs > 0) {
  686.                     newf += tin[xs-1] * lf;
  687.                 }
  688.                 for (k = xs; k < xe; k++) {
  689.                     newf += tin[k];
  690.                 }
  691.                 if (xe < w) {
  692.                     newf += tin[xe] * rf;
  693.                 }
  694.                 *op++ = newf/xfact;
  695.                 xs = xe + 1;
  696.                 lf = xs - xf;
  697.             }
  698.             SmoothY(t,out,h,x,y);
  699.             return;
  700.         }
  701.     }
  702.     // x > w
  703.      if (y == h) {
  704.         // x > w, y == h
  705.         UWORD j;
  706.         UBYTE *op = t;
  707.         UBYTE *tin = in;
  708.         UWORD i;
  709.         UBYTE *tint;
  710.  
  711.         AddMessageNo(MSG_SGTX);
  712.         SetMax(y);
  713.         for (j=0; j<y; j++) {
  714.             UWORD xs=0,xe;
  715.             float xf=0.0;
  716.  
  717.             SetCur(j);
  718.             tint = tin;
  719.             for (i=1; i<x; i++) {
  720.                 xf += xfact;
  721.                 xe = (UWORD)xf;
  722.                 if (xs == xe) {
  723.                     *op++ = *tint;
  724.                 }
  725.                 else {
  726.                     float lf,rf;
  727.  
  728.                     rf = xf - floor(xf);
  729.                     lf = xfact - rf;
  730.                     *op++ = ((*tint * lf) + (tint[1] * rf)) / xfact;
  731.                     tint++;
  732.                     xs = xe;
  733.                 }
  734.             }
  735.             *op++ = *tint;
  736.             tin += w;
  737.         }
  738.         SmoothX(t,out,w,x,y);
  739.         return;
  740.     }
  741.     if (y > h) {
  742.         // x > w, y > h
  743.         UWORD j;
  744.         UWORD ys=0,ye;
  745.         float yf=0.0;
  746.         UBYTE *op = t;
  747.         UBYTE *tin;
  748.         UWORD i;
  749.         float divf = xfact * yfact;
  750.         UWORD xs,xe;
  751.         float xf;
  752.  
  753.         AddMessageNo(MSG_SGTXGTY);
  754.         SetMax(y);
  755.         for (j=1; j<y; j++) {
  756.  
  757.             SetCur(j);
  758.             xs=0;
  759.             xf=0.0;
  760.             yf += yfact;
  761.             ye = (UWORD)yf;
  762.             tin = in + (ys * w);
  763.  
  764.             if (ys == ye) {
  765.                 for (i=1; i<x; i++) {
  766.                     xf += xfact;
  767.                     xe = (UWORD)xf;
  768.                     if (xs == xe) {
  769.                         *op++ = *tin;
  770.                     }
  771.                     else {
  772.                         float lf,rf;
  773.  
  774.                         rf = xf - floor(xf);
  775.                         lf = xfact - rf;
  776.                         *op++ = ((*tin * lf) + (tin[1] * rf)) / xfact;
  777.                         tin++;
  778.                         xs = xe;
  779.                     }
  780.                 }
  781.                 *op++ = *tin;
  782.             }
  783.             else {
  784.                 float tf,bf;
  785.  
  786.                 bf = yf - floor(yf);
  787.                 tf = yfact - bf;
  788.                 for (i=1; i<x; i++) {
  789.                     xf += xfact;
  790.                     xe = (UWORD)xf;
  791.                     if (xs == xe) {
  792.                         *op++ = ((*tin * tf) + (tin[w] * bf)) / yfact;
  793.                     }
  794.                     else {
  795.                         float lf,rf;
  796.  
  797.                         rf = xf - floor(xf);
  798.                         lf = xfact - rf;
  799.                         *op++ = ((*tin * lf * tf) + (tin[1] * rf * tf) +
  800.                                     (tin[w] * lf * bf) + (tin[w+1] * rf * bf)) / divf;
  801.                         tin++;
  802.                         xs = xe;
  803.                     }
  804.                 }
  805.                 *op++ = *tin;
  806.                 ys = ye;
  807.             }
  808.         }
  809.         tin = in + ((h-1) * w);
  810.         xf = 0.0;
  811.         xs = 0;
  812.         for (i=1; i<x; i++) {
  813.             xf += xfact;
  814.             xe = (UWORD)xf;
  815.             if (xs == xe) {
  816.                 *op++ = *tin;
  817.             }
  818.             else {
  819.                 float lf,rf;
  820.  
  821.                 rf = xf - floor(xf);
  822.                 lf = xfact - rf;
  823.                 *op++ = ((*tin * lf) + (tin[1] * rf)) / xfact;
  824.                 tin++;
  825.                 xs = xe;
  826.             }
  827.         }
  828.         *op = *tin;
  829.         SmoothXY(t,out,w,h,x,y);
  830.         return;
  831.     }
  832.     {
  833.         // x > w, y < h
  834.         UWORD j;
  835.         UBYTE *op = t;
  836.         float tf=0.0, bf;
  837.         float yf = 0.0;
  838.         UWORD ys=0,ye;
  839.         UBYTE *tin;
  840.         float divf = xfact * yfact;
  841.  
  842.         AddMessageNo(MSG_SGTXLTY);
  843.         SetMax(y);
  844.         for (j=0; j<y; j++) {
  845.             UWORD i;
  846.             UBYTE *tint;
  847.             float newf;
  848.             UWORD l;
  849.             UWORD xs=0,xe;
  850.             float xf=0.0;
  851.  
  852.             SetCur(j);
  853.             yf += yfact;
  854.             ye = (UWORD)yf;
  855.             bf = yf - ye;
  856.             if (ys > 0) {
  857.                 tin = in + ((ys-1) * w);
  858.             }
  859.             else {
  860.                 tin = in + (ys * w);
  861.             }
  862.  
  863.             for (i=1; i<x; i++) {
  864.                 newf=0.0;
  865.                 xf += xfact;
  866.                 xe = (UWORD)xf;
  867.                 tint = tin;
  868.  
  869.                 if (xs == xe) {
  870.                     if (ys > 0) {
  871.                         newf += tint[xs] * tf;
  872.                         tint += w;
  873.                     }
  874.                     for (l = ys; l < ye; l++) {
  875.                         newf += tint[xs];
  876.                         tint += w;
  877.                     }
  878.                     if (ye < h) {
  879.                         newf += tint[xs] * bf;
  880.                     }
  881.                     *op++ = newf/yfact;
  882.                 }
  883.                 else {
  884.                     float lf,rf;
  885.  
  886.                     rf = xf - floor(xf);
  887.                     lf = xfact - rf;
  888.                     if (ys > 0) {
  889.                         newf += ((tint[xs] * lf) + (tint[xe] * rf)) * tf;
  890.                         tint += w;
  891.                     }
  892.                     for (l = ys; l < ye; l++) {
  893.                         newf += ((tint[xs] * lf) + (tint[xe] * rf));
  894.                         tint += w;
  895.                     }
  896.                     if (ye < h) {
  897.                         newf += ((tint[xs] * lf) + (tint[xe] * rf)) * bf;
  898.                     }
  899.                     *op++ = newf/divf;
  900.                     xs = xe;
  901.                 }
  902.             }
  903.             tint = tin;
  904.             newf = 0.0;
  905.             if (ys > 0) {
  906.                 newf += tint[w-1] * tf;
  907.                 tint += w;
  908.             }
  909.             for (l = ys; l < ye; l++) {
  910.                 newf += tint[w-1];
  911.                 tint += w;
  912.             }
  913.             if (ye < h) {
  914.                 newf += tint[w-1] * bf;
  915.             }
  916.             *op++ = newf/yfact;
  917.             ys = ye + 1;
  918.             tf = ys - yf;
  919.         }
  920.         SmoothX(t,out,w,x,y);
  921.         return;
  922.     }
  923. }
  924.  
  925. static void
  926. SmoothX(UBYTE *in,UBYTE *out,UWORD w,UWORD x,UWORD y) {
  927.     int t;
  928.     int i,j;
  929.     UBYTE *p,*o;
  930.  
  931.     AddMessageNo(MSG_SMX);
  932.     t = x/w;
  933.     if (t < 2) {    // less than 2 times size
  934.         AddMessageNo(MSG_COPY);
  935.         memcpy(out,in,x*y);
  936.         return;
  937.     }
  938.     if (t < 3) {    // less than 3 times the size
  939.         p = in;
  940.         o = out;
  941.         AddMessageNo(MSG_LT3);
  942.         SetMax(y);
  943.         for (j = 0; j < y; ++j) {
  944.             SetCur(j);
  945.             for (i = 1; i < x; ++i) {    // Skip first column
  946.                 *o++ = (*p + p[1])>>1;
  947.                 ++p;
  948.             }
  949.             *o++ = *p++;
  950.         }
  951.         return;
  952.     }    // >= 3 times size
  953.     p = in;
  954.     o = out;
  955.     AddMessageNo(MSG_GE3);
  956.     SetMax(y);
  957.     for (j = 0; j < y; ++j) {
  958.         SetCur(j);
  959.         *o++ = *p;
  960.         for (i = 2; i < x; ++i) {    // Skip first and last columns
  961.             *o++ = (*p + p[1] + p[2])/3;
  962.             ++p;
  963.         }
  964.         ++p;
  965.         *o++ = *p++;
  966.     }
  967. }
  968.  
  969. static void
  970. SmoothY(UBYTE *in,UBYTE *out,UWORD h,UWORD x,UWORD y) {
  971.     int t;
  972.     int i,j;
  973.     UBYTE *p,*p1,*p2,*o;
  974.  
  975.     AddMessageNo(MSG_SMY);
  976.     t = y/h;
  977.     if (t < 2) {
  978.         AddMessageNo(MSG_COPY);
  979.         memcpy(out,in,x*y);
  980.         return;
  981.     }
  982.     if (t < 3) {
  983.         p = in;
  984.         p1 = in;
  985.         o = out;
  986.         
  987.         for (i = 0; i < x; ++i) {
  988.             *o++ = *p++;
  989.         }
  990.         AddMessageNo(MSG_LT3);
  991.         SetMax(y);
  992.         for (j = 1; j < y; ++j) {    // Skip first row
  993.             SetCur(j);
  994.             for (i = 0; i < x; ++i) {
  995.                 *o++ = (*p++ + *p1++)>>1;
  996.             }
  997.         }
  998.         return;
  999.     }
  1000.     p1 = in;
  1001.     p = in;
  1002.     p2 = in + x + x;
  1003.     o = out;
  1004.     for (i = 0; i < x; ++i) {
  1005.         *o++ = *p++;
  1006.     }
  1007.     AddMessageNo(MSG_GE3);
  1008.     SetMax(y);
  1009.     for (j = 2; j < y; ++j) {    // Skip first and last rows
  1010.         SetCur(j);
  1011.         for (i = 0; i < x; ++i) {
  1012.             *o++ = (*p++ + *p1++ + *p2++)/3;
  1013.         }
  1014.     }
  1015.     for (i = 0; i < x; ++i) {
  1016.         *o++ = *p++;
  1017.     }
  1018. }
  1019.  
  1020. static void
  1021. SmoothXY(UBYTE *in,UBYTE *out,UWORD w,UWORD h,UWORD x,UWORD y) {
  1022.     int tx,ty;
  1023.     int i,j;
  1024.     UBYTE *p,*p1,*p2,*o;
  1025.  
  1026.     AddMessageNo(MSG_SMXY);
  1027.     tx = x/w;
  1028.  
  1029.     ty = y/h;
  1030.  
  1031.     if ((tx < 2) && (ty < 2)) {
  1032.         AddMessageNo(MSG_COPY);
  1033.         memcpy(out,in,x*y);
  1034.         return;
  1035.     }
  1036.  
  1037.     if (ty < 2) {    // No y smooth required
  1038.         SmoothX(in,out,w,x,y);
  1039.         return;
  1040.     }
  1041.  
  1042.     if (tx < 2) {    // No x smooth required
  1043.         SmoothY(in,out,h,x,y);
  1044.         return;
  1045.     }
  1046.  
  1047.     if (tx < 3) {
  1048.         if (ty < 3) {
  1049.             p = in;
  1050.             p1 = in;
  1051.             o = out;
  1052.             *o++ = *p;
  1053.             for (i = 1; i < x; ++i) {
  1054.                 *o++ = (*p + p[1])>>1;
  1055.                 ++p;
  1056.             }
  1057.             ++p;
  1058.             AddMessageNo(MSG_XLT3YLT3);
  1059.             SetMax(y);
  1060.             for (j = 1; j < y; ++j) {
  1061.                 SetCur(j);
  1062.                 *o++ = (*p + *p1)>>1;
  1063.                 for (i = 1; i < x; ++i) {
  1064.                     *o++ = (*p + p[1] + *p1 + p1[1])>>2;
  1065.                     ++p;
  1066.                     ++p1;
  1067.                 }
  1068.                 ++p;
  1069.                 ++p1;
  1070.             }
  1071.             return;
  1072.         } // tx < 3 ty >=3
  1073.         p1 = in;
  1074.         p = in;
  1075.         p2 = in + x + x;
  1076.         o = out;
  1077.  
  1078.         *o++ = *p;
  1079.         for (i = 1; i < x; ++i) {
  1080.             *o++ = (*p + p[1])>>1;
  1081.             ++p;
  1082.         }
  1083.         ++p;
  1084.         AddMessageNo(MSG_XLT3YGE3);
  1085.         SetMax(y);
  1086.         for (j = 2; j < y; ++j) {
  1087.             SetCur(j);
  1088.             *o++ = (*p + *p1 + *p2)/3;
  1089.             for (i = 1; i < x; ++i) {
  1090.                 *o++ = (*p + p[1] + *p1 + p1[1] + *p2 + p2[1])/6;
  1091.                 ++p;
  1092.                 ++p1;
  1093.                 ++p2;
  1094.             }
  1095.             ++p;
  1096.             ++p1;
  1097.             ++p2;
  1098.         }
  1099.         *o++ = *p;
  1100.         for (i = 1; i < x; ++i) {
  1101.             *o++ = (*p + p[1])>>1;
  1102.             ++p;
  1103.         }
  1104.         return;
  1105.     } // tx >= 3
  1106.     if (ty < 3) {
  1107.         p1 = in;
  1108.         p = in;
  1109.         o = out;
  1110.         *o++ = *p;
  1111.         for (i = 2; i < x; ++i) {    // Skip first and last columns
  1112.             *o++ = (*p + p[1] + p[2])/3;
  1113.             ++p;
  1114.         }
  1115.         ++p;
  1116.         *o++ = *p++;
  1117.         AddMessageNo(MSG_XGE3YLT3);
  1118.         SetMax(y);
  1119.         for (j = 1; j < y; ++j) {
  1120.             SetCur(j);
  1121.             *o++ = (*p + *p1)>>1;
  1122.             for (i = 2; i < x; ++i) {
  1123.                 *o++ = (*p + p[1] + p[2] + *p1 + p1[1] + p1[2])/6;
  1124.                 ++p;
  1125.                 ++p1;
  1126.             }
  1127.             ++p1;
  1128.             ++p;
  1129.  
  1130.             *o++ = (*p++ + *p1++)>>1;
  1131.         }
  1132.         return;
  1133.     }    // tx >= 3, ty >= 3
  1134.     p1 = in;
  1135.     p = in;
  1136.     p2 = in + x + x;
  1137.     o = out;
  1138.  
  1139.     *o++ = *p;
  1140.     for (i = 2; i < x; ++i) {    // Skip first and last columns
  1141.         *o++ = (*p + p[1] + p[2])/3;
  1142.         ++p;
  1143.     }
  1144.     ++p;
  1145.     *o++ = *p++;
  1146.  
  1147.     AddMessageNo(MSG_XGE3YGE3);
  1148.     SetMax(y);
  1149.     for (j = 2; j < y; ++j) {
  1150.         SetCur(j);
  1151.         *o++ = (*p + *p1 + *p2)/3;
  1152.         for (i = 2; i < x; ++i) {
  1153.             *o++ = (*p + p[1] + p[2] + *p1 + p1[1] + p1[2] + *p2 + p2[1] + p2[2])/9;
  1154.             ++p;
  1155.             ++p1;
  1156.             ++p2;
  1157.         }
  1158.         ++p1;
  1159.         ++p;
  1160.         ++p2;
  1161.  
  1162.         *o++ = (*p++ + *p1++ + *p2++)/3;
  1163.     }
  1164.     *o++ = *p;
  1165.     for (i = 2; i < x; ++i) {    // Skip first and last columns
  1166.         *o++ = (*p + p[1] + p[2])/3;
  1167.         ++p;
  1168.     }
  1169.     *o = *p;
  1170. }
  1171.  
  1172. /****** MPImage.library/MPScaleRGB ***************************************
  1173. *
  1174. *   NAME   
  1175. *  MPScaleRGB -- Scales an RGB image (V7)
  1176. *
  1177. *   SYNOPSIS
  1178. *  MPScaleRGB( Old,New,Temp)
  1179. *              A0  A1  A2
  1180. *
  1181. *  void MPScaleRGB
  1182. *           ( struct MPProcess *,struct MPProcess *,struct MPProcess *);
  1183. *
  1184. *   FUNCTION
  1185. *  Scales an RGB image.
  1186. *
  1187. *   INPUTS
  1188. *  Old      - Contains the Red,Green and Blue chunky pixels
  1189. *             and the Width and Height of the current image.
  1190. *  New      - Contains the Red,Green and Blue chunky pixels
  1191. *             and the Width and Height for the new image.
  1192. *  Temp     - Contains 3 temporary buffers sized for the new image.
  1193. *
  1194. *   RESULT
  1195. *  The data pointed to by New->Red/Green/Blue is updated to 
  1196. *  the scaled image.
  1197. *
  1198. *   EXAMPLE
  1199. *
  1200. *   NOTES
  1201. *
  1202. *   BUGS
  1203. *  Not tested.
  1204. *
  1205. *   SEE ALSO
  1206. *  MPScaleGrey().
  1207. *
  1208. *****************************************************************************
  1209. *
  1210. */
  1211.  
  1212. void __asm __saveds
  1213. MPScaleRGB(register __a0 struct MPProcess *Old,register __a1 struct MPProcess *New,
  1214.                 register __a2 struct MPProcess *Temp) {
  1215.     RescaleXYRGB(Old->Red,Old->Green,Old->Blue,Old->Width,Old->Height,
  1216.                      New->Red,New->Green,New->Blue,New->Width,New->Height,
  1217.                      Temp->Red,Temp->Green,Temp->Blue);
  1218. }
  1219.  
  1220. /* inr = chunky in r
  1221.  * ing = chunky in g
  1222.  * inb = chunky in b
  1223.  * w  = old width
  1224.  * h  = old height
  1225.  * outr= chunky out r
  1226.  * outg= chunky out g
  1227.  * outb= chunky out b
  1228.  * x  = new width
  1229.  * y  = new height
  1230.  * tr  = Temp buffer r
  1231.  * tg  = Temp buffer g
  1232.  * tb  = Temp buffer b
  1233.  */
  1234. static
  1235. void
  1236. RescaleXYRGB(UBYTE *inr,UBYTE *ing,UBYTE *inb,UWORD w,UWORD h,UBYTE *outr,UBYTE *outg,UBYTE *outb,
  1237.             UWORD x,UWORD y,UBYTE *tr,UBYTE *tg,UBYTE *tb) {
  1238.     float xfact,yfact;
  1239.  
  1240.     xfact = ((float)w)/x;
  1241.     yfact = ((float)h)/y;
  1242.  
  1243.     if (x == w) {
  1244.         if (y == h) {
  1245.             AddMessageNo(MSG_COPY);
  1246.             memcpy(outr,inr,w*h);
  1247.             memcpy(outg,ing,w*h);
  1248.             memcpy(outb,inb,w*h);
  1249.             return;
  1250.         }
  1251.         if (y < h) {
  1252.             // x == w, y < h
  1253.             UWORD j;
  1254.             UBYTE *opr = outr;
  1255.             UBYTE *opg = outg;
  1256.             UBYTE *opb = outb;
  1257.             float tf=0.0, bf;
  1258.             float yf = 0.0;
  1259.             UWORD ys=0,ye;
  1260.  
  1261.             AddMessageNo(MSG_SLTY);
  1262.             SetMax(y);
  1263.             for (j=0; j<y; j++) {
  1264.                 UWORD i;
  1265.                 UBYTE *tinr;
  1266.                 UBYTE *ting;
  1267.                 UBYTE *tinb;
  1268.  
  1269.                 SetCur(j);
  1270.                 yf += yfact;
  1271.                 ye = (UWORD)yf;
  1272.                 bf = yf - ye;
  1273.                 if (ys > 0) {
  1274.                     tinr = inr + ((ys-1) * w);
  1275.                     ting = ing + ((ys-1) * w);
  1276.                     tinb = inb + ((ys-1) * w);
  1277.                 }
  1278.                 else {
  1279.                     tinr = inr + (ys * w);
  1280.                     ting = ing + (ys * w);
  1281.                     tinb = inb + (ys * w);
  1282.                 }
  1283.  
  1284.                 for (i=0; i<x; i++) {
  1285.                     float newfr=0.0;
  1286.                     float newfg=0.0;
  1287.                     float newfb=0.0;
  1288.                     UWORD l;
  1289.                     UBYTE *tintr = tinr;
  1290.                     UBYTE *tintg = ting;
  1291.                     UBYTE *tintb = tinb;
  1292.  
  1293.                     if (ys > 0) {
  1294.                         newfr += tintr[i] * tf;
  1295.                         tintr += w;
  1296.                         newfg += tintg[i] * tf;
  1297.                         tintg += w;
  1298.                         newfb += tintb[i] * tf;
  1299.                         tintb += w;
  1300.                     }
  1301.                     for (l = ys; l < ye; l++) {
  1302.                         newfr += tintr[i];
  1303.                         tintr += w;
  1304.                         newfg += tintg[i];
  1305.                         tintg += w;
  1306.                         newfb += tintb[i];
  1307.                         tintb += w;
  1308.                     }
  1309.                     if (ye < h) {
  1310.                         newfr += tintr[i] * bf;
  1311.                         newfg += tintg[i] * bf;
  1312.                         newfb += tintb[i] * bf;
  1313.                     }
  1314.                     *opr++ = newfr/yfact;
  1315.                     *opg++ = newfg/yfact;
  1316.                     *opb++ = newfb/yfact;
  1317.                 }
  1318.                 ys = ye + 1;
  1319.                 tf = ys - yf;
  1320.             }
  1321.             return;
  1322.         }
  1323.         {
  1324.             // x == w, y > h
  1325.             UWORD j;
  1326.             UWORD ys=0,ye;
  1327.             float yf=0.0;
  1328.             UBYTE *opr = tr;
  1329.             UBYTE *tinr;
  1330.             UBYTE *opg = tg;
  1331.             UBYTE *ting;
  1332.             UBYTE *opb = tb;
  1333.             UBYTE *tinb;
  1334.             UWORD i;
  1335.  
  1336.             AddMessageNo(MSG_SGTY);
  1337.             SetMax(y);
  1338.             for (j=1; j<y; j++) {
  1339.  
  1340.                 SetCur(j);
  1341.                 yf += yfact;
  1342.                 ye = (UWORD)yf;
  1343.                 tinr = inr + (ys * w);
  1344.                 ting = ing + (ys * w);
  1345.                 tinb = inb + (ys * w);
  1346.  
  1347.                 if (ys == ye) {
  1348.                     for (i=0; i<x; i++) {
  1349.                         *opr++ = *tinr++;
  1350.                         *opg++ = *ting++;
  1351.                         *opb++ = *tinb++;
  1352.                     }
  1353.                 }
  1354.                 else {
  1355.                     float tf,bf;
  1356.  
  1357.                     bf = yf - floor(yf);
  1358.                     tf = yfact - bf;
  1359.                     for (i=0; i<x; i++) {
  1360.                         *opr++ = ((*tinr * tf) + (tinr[w] * bf)) / yfact;
  1361.                         tinr++;
  1362.                         *opg++ = ((*ting * tf) + (ting[w] * bf)) / yfact;
  1363.                         ting++;
  1364.                         *opb++ = ((*tinb * tf) + (tinb[w] * bf)) / yfact;
  1365.                         tinb++;
  1366.                     }
  1367.                     ys = ye;
  1368.                 }
  1369.             }
  1370.             tinr = inr + ((h-1) * w);
  1371.             ting = ing + ((h-1) * w);
  1372.             tinb = inb + ((h-1) * w);
  1373.             for (i=0; i<x; i++) {
  1374.                 *opr++ = *tinr++;
  1375.                 *opg++ = *ting++;
  1376.                 *opb++ = *tinb++;
  1377.             }
  1378.             SmoothY(tr,outr,h,x,y);
  1379.             SmoothY(tg,outg,h,x,y);
  1380.             SmoothY(tb,outb,h,x,y);
  1381.             return;
  1382.         }
  1383.     }
  1384.     // x != w
  1385.     if (x < w) {
  1386.         // x < w
  1387.         if (y == h) {
  1388.             // x < w, y == h
  1389.             UWORD j;
  1390.             UBYTE *opr = outr;
  1391.             UBYTE *tinr = inr;
  1392.             UBYTE *opg = outg;
  1393.             UBYTE *ting = ing;
  1394.             UBYTE *opb = outb;
  1395.             UBYTE *tinb = inb;
  1396.  
  1397.             AddMessageNo(MSG_SLTX);
  1398.             SetMax(y);
  1399.             for (j=0; j<y; j++) {
  1400.                 float xf = 0.0;
  1401.                 float lf=0.0,rf;
  1402.                 UWORD xs=0,xe;
  1403.                 UWORD i;
  1404.  
  1405.                 SetCur(j);
  1406.                 for (i=0; i<x; i++) {
  1407.                     float newfr=0.0;
  1408.                     float newfg=0.0;
  1409.                     float newfb=0.0;
  1410.                     UWORD k;
  1411.  
  1412.                     xf += xfact;
  1413.                     xe = (UWORD)xf;
  1414.                     rf = xf - xe;
  1415.  
  1416.                     if (xs > 0) {
  1417.                         newfr += tinr[xs-1] * lf;
  1418.                         newfg += ting[xs-1] * lf;
  1419.                         newfb += tinb[xs-1] * lf;
  1420.                     }
  1421.                     for (k = xs; k < xe; k++) {
  1422.                         newfr += tinr[k];
  1423.                         newfg += ting[k];
  1424.                         newfb += tinb[k];
  1425.                     }
  1426.                     if (xe < w) {
  1427.                         newfr += tinr[xe] * rf;
  1428.                         newfg += ting[xe] * rf;
  1429.                         newfb += tinb[xe] * rf;
  1430.                     }
  1431.                     *opr++ = newfr/xfact;
  1432.                     *opg++ = newfg/xfact;
  1433.                     *opb++ = newfb/xfact;
  1434.                     xs = xe + 1;
  1435.                     lf = xs - xf;
  1436.                 }
  1437.                 tinr += w;
  1438.                 ting += w;
  1439.                 tinb += w;
  1440.             }
  1441.             return;
  1442.         }
  1443.         if (y < h) {
  1444.             // x < w, y < h
  1445.             UWORD j;
  1446.             float divf;
  1447.             UBYTE *opr = outr;
  1448.             UBYTE *opg = outg;
  1449.             UBYTE *opb = outb;
  1450.             float tf=0.0, bf;
  1451.             float yf = 0.0;
  1452.             UWORD ys=0,ye;
  1453.  
  1454.             divf = xfact * yfact;
  1455.  
  1456.             AddMessageNo(MSG_SLTXLTY);
  1457.             SetMax(y);
  1458.             for (j=0; j<y; j++) {
  1459.                 float xf = 0.0;
  1460.                 float lf=0.0,rf;
  1461.                 UWORD xs=0,xe;
  1462.                 UWORD i;
  1463.  
  1464.                 SetCur(j);
  1465.                 yf += yfact;
  1466.                 ye = (UWORD)yf;
  1467.                 bf = yf - ye;
  1468.  
  1469.                 for (i=0; i<x; i++) {
  1470.                     float newfr=0.0;
  1471.                     UBYTE *tinr;
  1472.                     float newfg=0.0;
  1473.                     UBYTE *ting;
  1474.                     float newfb=0.0;
  1475.                     UBYTE *tinb;
  1476.                     UWORD l;
  1477.  
  1478.                     xf += xfact;
  1479.                     xe = (UWORD)xf;
  1480.                     rf = xf - xe;
  1481.  
  1482.                     if (ys > 0) {
  1483.                         UWORD k;
  1484.                         tinr = inr + ((ys-1) * w);
  1485.                         ting = ing + ((ys-1) * w);
  1486.                         tinb = inb + ((ys-1) * w);
  1487.                         if (xs > 0) {
  1488.                             newfr += tinr[xs-1] * lf * tf;
  1489.                             newfg += ting[xs-1] * lf * tf;
  1490.                             newfb += tinb[xs-1] * lf * tf;
  1491.                         }
  1492.                         for (k = xs; k < xe; k++) {
  1493.                             newfr += tinr[k] * tf;
  1494.                             newfg += ting[k] * tf;
  1495.                             newfb += tinb[k] * tf;
  1496.                         }
  1497.                         if (xe < w) {
  1498.                             newfr += tinr[xe] * rf * tf;
  1499.                             newfg += ting[xe] * rf * tf;
  1500.                             newfb += tinb[xe] * rf * tf;
  1501.                         }
  1502.                         tinr += w;
  1503.                         ting += w;
  1504.                         tinb += w;
  1505.                     }
  1506.                     else {
  1507.                         tinr = inr + (ys * w);
  1508.                         ting = ing + (ys * w);
  1509.                         tinb = inb + (ys * w);
  1510.                     }
  1511.                     for (l = ys; l < ye; l++) {
  1512.                         UWORD k;
  1513.                         if (xs > 0) {
  1514.                             newfr += tinr[xs-1] * lf;
  1515.                             newfg += ting[xs-1] * lf;
  1516.                             newfb += tinb[xs-1] * lf;
  1517.                         }
  1518.                         for (k = xs; k < xe; k++) {
  1519.                             newfr += tinr[k];
  1520.                             newfg += ting[k];
  1521.                             newfb += tinb[k];
  1522.                         }
  1523.                         if (xe < w) {
  1524.                             newfr += tinr[xe] * rf;
  1525.                             newfg += ting[xe] * rf;
  1526.                             newfb += tinb[xe] * rf;
  1527.                         }
  1528.                         tinr += w;
  1529.                         ting += w;
  1530.                         tinb += w;
  1531.                     }
  1532.                     if (ye < h) {
  1533.                         UWORD k;
  1534.                         newfr += tinr[xs-1] * lf * bf;
  1535.                         newfg += ting[xs-1] * lf * bf;
  1536.                         newfb += tinb[xs-1] * lf * bf;
  1537.                         for (k = xs; k < xe; k++) {
  1538.                             newfr += tinr[k] * bf;
  1539.                             newfg += ting[k] * bf;
  1540.                             newfb += tinb[k] * bf;
  1541.                         }
  1542.                         if (xe < w) {
  1543.                             newfr += tinr[xe] * rf * bf;
  1544.                             newfg += ting[xe] * rf * bf;
  1545.                             newfb += tinb[xe] * rf * bf;
  1546.                         }
  1547.                     }
  1548.                     *opr++ = newfr/divf;
  1549.                     *opg++ = newfg/divf;
  1550.                     *opb++ = newfb/divf;
  1551.                     xs = xe + 1;
  1552.                     lf = xs - xf;
  1553.                 }
  1554.                 ys = ye + 1;
  1555.                 tf = ys - yf;
  1556.             }
  1557.             return;
  1558.         }
  1559.         {
  1560.             // x < w, y > h
  1561.             UWORD j;
  1562.             UWORD ys=0,ye;
  1563.             float yf=0.0;
  1564.             UBYTE *opr = tr;
  1565.             UBYTE *tinr;
  1566.             UBYTE *opg = tg;
  1567.             UBYTE *ting;
  1568.             UBYTE *opb = tb;
  1569.             UBYTE *tinb;
  1570.             UWORD i;
  1571.             float divf = xfact * yfact;
  1572.             UWORD xs,xe;
  1573.             float xf;
  1574.             float lf,rf;
  1575.  
  1576.             AddMessageNo(MSG_SLTXGTY);
  1577.             SetMax(y);
  1578.             for (j=1; j<y; j++) {
  1579.  
  1580.                 SetCur(j);
  1581.                 xf = 0.0;
  1582.                 lf = 0.0;
  1583.                 xs = 0;
  1584.                 yf += yfact;
  1585.                 ye = (UWORD)yf;
  1586.                 tinr = inr + (ys * w);
  1587.                 ting = ing + (ys * w);
  1588.                 tinb = inb + (ys * w);
  1589.  
  1590.                 if (ys == ye) {
  1591.                     for (i=0; i<x; i++) {
  1592.                         float newfr=0.0;
  1593.                         float newfg=0.0;
  1594.                         float newfb=0.0;
  1595.                         UWORD k;
  1596.  
  1597.                         xf += xfact;
  1598.                         xe = (UWORD)xf;
  1599.                         rf = xf - xe;
  1600.  
  1601.                         if (xs > 0) {
  1602.                             newfr += tinr[xs-1] * lf;
  1603.                             newfg += ting[xs-1] * lf;
  1604.                             newfb += tinb[xs-1] * lf;
  1605.                         }
  1606.                         for (k = xs; k < xe; k++) {
  1607.                             newfr += tinr[k];
  1608.                             newfg += ting[k];
  1609.                             newfb += tinb[k];
  1610.                         }
  1611.                         if (xe < w) {
  1612.                             newfr += tinr[xe] * rf;
  1613.                             newfg += ting[xe] * rf;
  1614.                             newfb += tinb[xe] * rf;
  1615.                         }
  1616.                         *opr++ = newfr/xfact;
  1617.                         *opg++ = newfg/xfact;
  1618.                         *opb++ = newfb/xfact;
  1619.                         xs = xe + 1;
  1620.                         lf = xs - xf;
  1621.                     }
  1622.                 }
  1623.                 else {
  1624.                     float tf,bf;
  1625.                     UWORD k;
  1626.  
  1627.                     bf = yf - floor(yf);
  1628.                     tf = yfact - bf;
  1629.  
  1630.                     for (i=0; i<x; i++) {
  1631.                         float newfr=0.0;
  1632.                         float newfg=0.0;
  1633.                         float newfb=0.0;
  1634.  
  1635.                         xf += xfact;
  1636.                         xe = (UWORD)xf;
  1637.                         rf = xf - xe;
  1638.  
  1639.                         if (xs > 0) {
  1640.                             newfr += ((tinr[xs-1] * tf) + (tinr[xs-1+w] * bf)) * lf;
  1641.                             newfg += ((ting[xs-1] * tf) + (ting[xs-1+w] * bf)) * lf;
  1642.                             newfb += ((tinb[xs-1] * tf) + (tinb[xs-1+w] * bf)) * lf;
  1643.                         }
  1644.                         for (k = xs; k < xe; k++) {
  1645.                             newfr += (tinr[k] * tf) + (tinr[k+w] * bf);
  1646.                             newfg += (ting[k] * tf) + (ting[k+w] * bf);
  1647.                             newfb += (tinb[k] * tf) + (tinb[k+w] * bf);
  1648.                         }
  1649.                         if (xe < w) {
  1650.                             newfr += ((tinr[xe] * tf) + (tinr[xe+w] * bf)) * rf;
  1651.                             newfg += ((ting[xe] * tf) + (ting[xe+w] * bf)) * rf;
  1652.                             newfb += ((tinb[xe] * tf) + (tinb[xe+w] * bf)) * rf;
  1653.                         }
  1654.                         *opr++ = newfr/divf;
  1655.                         *opg++ = newfg/divf;
  1656.                         *opb++ = newfb/divf;
  1657.                         xs = xe + 1;
  1658.                         lf = xs - xf;
  1659.                     }
  1660.                     ys = ye;
  1661.                 }
  1662.             }
  1663.             tinr = inr + ((h-1) * w);
  1664.             ting = ing + ((h-1) * w);
  1665.             tinb = inb + ((h-1) * w);
  1666.             xs = 0;
  1667.             lf = 0.0;
  1668.             xf = 0.0;
  1669.             for (i=0; i<x; i++) {
  1670.                 float newfr=0.0;
  1671.                 float newfg=0.0;
  1672.                 float newfb=0.0;
  1673.                 UWORD k;
  1674.  
  1675.                 xf += xfact;
  1676.                 xe = (UWORD)xf;
  1677.                 rf = xf - xe;
  1678.  
  1679.                 if (xs > 0) {
  1680.                     newfr += tinr[xs-1] * lf;
  1681.                     newfg += ting[xs-1] * lf;
  1682.                     newfb += tinb[xs-1] * lf;
  1683.                 }
  1684.                 for (k = xs; k < xe; k++) {
  1685.                     newfr += tinr[k];
  1686.                     newfg += ting[k];
  1687.                     newfb += tinb[k];
  1688.                 }
  1689.                 if (xe < w) {
  1690.                     newfr += tinr[xe] * rf;
  1691.                     newfg += ting[xe] * rf;
  1692.                     newfb += tinb[xe] * rf;
  1693.                 }
  1694.                 *opr++ = newfr/xfact;
  1695.                 *opg++ = newfg/xfact;
  1696.                 *opb++ = newfb/xfact;
  1697.                 xs = xe + 1;
  1698.                 lf = xs - xf;
  1699.             }
  1700.             SmoothY(tr,outr,h,x,y);
  1701.             SmoothY(tg,outg,h,x,y);
  1702.             SmoothY(tb,outb,h,x,y);
  1703.             return;
  1704.         }
  1705.     }
  1706.     // x > w
  1707.      if (y == h) {
  1708.         // x > w, y == h
  1709.         UWORD j;
  1710.         UBYTE *opr = tr;
  1711.         UBYTE *tinr = inr;
  1712.         UBYTE *opg = tg;
  1713.         UBYTE *ting = ing;
  1714.         UBYTE *opb = tb;
  1715.         UBYTE *tinb = inb;
  1716.         UWORD i;
  1717.         UBYTE *tintr;
  1718.         UBYTE *tintg;
  1719.         UBYTE *tintb;
  1720.  
  1721.         AddMessageNo(MSG_SGTX);
  1722.         SetMax(y);
  1723.         for (j=0; j<y; j++) {
  1724.             UWORD xs=0,xe;
  1725.             float xf=0.0;
  1726.  
  1727.             SetCur(j);
  1728.             tintr = tinr;
  1729.             tintg = ting;
  1730.             tintb = tinb;
  1731.             for (i=1; i<x; i++) {
  1732.                 xf += xfact;
  1733.                 xe = (UWORD)xf;
  1734.                 if (xs == xe) {
  1735.                     *opr++ = *tintr;
  1736.                     *opg++ = *tintg;
  1737.                     *opb++ = *tintb;
  1738.                 }
  1739.                 else {
  1740.                     float lf,rf;
  1741.  
  1742.                     rf = xf - floor(xf);
  1743.                     lf = xfact - rf;
  1744.                     *opr++ = ((*tintr * lf) + (tintr[1] * rf)) / xfact;
  1745.                     *opg++ = ((*tintg * lf) + (tintg[1] * rf)) / xfact;
  1746.                     *opb++ = ((*tintb * lf) + (tintb[1] * rf)) / xfact;
  1747.                     tintr++;
  1748.                     tintg++;
  1749.                     tintb++;
  1750.                     xs = xe;
  1751.                 }
  1752.             }
  1753.             *opr++ = *tintr;
  1754.             tinr += w;
  1755.             *opg++ = *tintg;
  1756.             ting += w;
  1757.             *opb++ = *tintb;
  1758.             tinb += w;
  1759.         }
  1760.         SmoothX(tr,outr,w,x,y);
  1761.         SmoothX(tg,outg,w,x,y);
  1762.         SmoothX(tb,outb,w,x,y);
  1763.         return;
  1764.     }
  1765.     if (y > h) {
  1766.         // x > w, y > h
  1767.         UWORD j;
  1768.         UWORD ys=0,ye;
  1769.         float yf=0.0;
  1770.         UBYTE *opr = tr;
  1771.         UBYTE *tinr;
  1772.         UBYTE *opg = tg;
  1773.         UBYTE *ting;
  1774.         UBYTE *opb = tb;
  1775.         UBYTE *tinb;
  1776.         UWORD i;
  1777.         float divf = xfact * yfact;
  1778.         UWORD xs,xe;
  1779.         float xf;
  1780.  
  1781.         AddMessageNo(MSG_SGTXGTY);
  1782.         SetMax(y);
  1783.         for (j=1; j<y; j++) {
  1784.  
  1785.             SetCur(j);
  1786.             xs=0;
  1787.             xf=0.0;
  1788.             yf += yfact;
  1789.             ye = (UWORD)yf;
  1790.             tinr = inr + (ys * w);
  1791.             ting = ing + (ys * w);
  1792.             tinb = inb + (ys * w);
  1793.  
  1794.             if (ys == ye) {
  1795.                 for (i=1; i<x; i++) {
  1796.                     xf += xfact;
  1797.                     xe = (UWORD)xf;
  1798.                     if (xs == xe) {
  1799.                         *opr++ = *tinr;
  1800.                         *opg++ = *ting;
  1801.                         *opb++ = *tinb;
  1802.                     }
  1803.                     else {
  1804.                         float lf,rf;
  1805.  
  1806.                         rf = xf - floor(xf);
  1807.                         lf = xfact - rf;
  1808.                         *opr++ = ((*tinr * lf) + (tinr[1] * rf)) / xfact;
  1809.                         tinr++;
  1810.                         *opg++ = ((*ting * lf) + (ting[1] * rf)) / xfact;
  1811.                         ting++;
  1812.                         *opb++ = ((*tinb * lf) + (tinb[1] * rf)) / xfact;
  1813.                         tinb++;
  1814.                         xs = xe;
  1815.                     }
  1816.                 }
  1817.                 *opr++ = *tinr;
  1818.                 *opg++ = *ting;
  1819.                 *opb++ = *tinb;
  1820.             }
  1821.             else {
  1822.                 float tf,bf;
  1823.  
  1824.                 bf = yf - floor(yf);
  1825.                 tf = yfact - bf;
  1826.                 for (i=1; i<x; i++) {
  1827.                     xf += xfact;
  1828.                     xe = (UWORD)xf;
  1829.                     if (xs == xe) {
  1830.                         *opr++ = ((*tinr * tf) + (tinr[w] * bf)) / yfact;
  1831.                         *opg++ = ((*ting * tf) + (ting[w] * bf)) / yfact;
  1832.                         *opb++ = ((*tinb * tf) + (tinb[w] * bf)) / yfact;
  1833.                     }
  1834.                     else {
  1835.                         float lf,rf;
  1836.  
  1837.                         rf = xf - floor(xf);
  1838.                         lf = xfact - rf;
  1839.                         *opr++ = ((*tinr * lf * tf) + (tinr[1] * rf * tf) +
  1840.                                     (tinr[w] * lf * bf) + (tinr[w+1] * rf * bf)) / divf;
  1841.                         tinr++;
  1842.                         *opg++ = ((*ting * lf * tf) + (ting[1] * rf * tf) +
  1843.                                     (ting[w] * lf * bf) + (ting[w+1] * rf * bf)) / divf;
  1844.                         ting++;
  1845.                         *opb++ = ((*tinb * lf * tf) + (tinb[1] * rf * tf) +
  1846.                                     (tinb[w] * lf * bf) + (tinb[w+1] * rf * bf)) / divf;
  1847.                         tinb++;
  1848.                         xs = xe;
  1849.                     }
  1850.                 }
  1851.                 *opr++ = *tinr;
  1852.                 *opg++ = *ting;
  1853.                 *opb++ = *tinb;
  1854.                 ys = ye;
  1855.             }
  1856.         }
  1857.         tinr = inr + ((h-1) * w);
  1858.         ting = ing + ((h-1) * w);
  1859.         tinb = inb + ((h-1) * w);
  1860.         xf = 0.0;
  1861.         xs = 0;
  1862.         for (i=1; i<x; i++) {
  1863.             xf += xfact;
  1864.             xe = (UWORD)xf;
  1865.             if (xs == xe) {
  1866.                 *opr++ = *tinr;
  1867.                 *opg++ = *ting;
  1868.                 *opb++ = *tinb;
  1869.             }
  1870.             else {
  1871.                 float lf,rf;
  1872.  
  1873.                 rf = xf - floor(xf);
  1874.                 lf = xfact - rf;
  1875.                 *opr++ = ((*tinr * lf) + (tinr[1] * rf)) / xfact;
  1876.                 tinr++;
  1877.                 *opg++ = ((*ting * lf) + (ting[1] * rf)) / xfact;
  1878.                 ting++;
  1879.                 *opb++ = ((*tinb * lf) + (tinb[1] * rf)) / xfact;
  1880.                 tinb++;
  1881.                 xs = xe;
  1882.             }
  1883.         }
  1884.         *opr = *tinr;
  1885.         *opg = *ting;
  1886.         *opb = *tinb;
  1887.         SmoothXY(tr,outr,w,h,x,y);
  1888.         SmoothXY(tg,outg,w,h,x,y);
  1889.         SmoothXY(tb,outb,w,h,x,y);
  1890.         return;
  1891.     }
  1892.     {
  1893.         // x > w, y < h
  1894.         UWORD j;
  1895.         UBYTE *opr = tr;
  1896.         UBYTE *opg = tg;
  1897.         UBYTE *opb = tb;
  1898.         float tf=0.0, bf;
  1899.         float yf = 0.0;
  1900.         UWORD ys=0,ye;
  1901.         UBYTE *tinr;
  1902.         UBYTE *ting;
  1903.         UBYTE *tinb;
  1904.         float divf = xfact * yfact;
  1905.  
  1906.         AddMessageNo(MSG_SGTXLTY);
  1907.         SetMax(y);
  1908.         for (j=0; j<y; j++) {
  1909.             UWORD i;
  1910.             UBYTE *tintr;
  1911.             float newfr;
  1912.             UBYTE *tintg;
  1913.             float newfg;
  1914.             UBYTE *tintb;
  1915.             float newfb;
  1916.             UWORD l;
  1917.             UWORD xs=0,xe;
  1918.             float xf=0.0;
  1919.  
  1920.             SetCur(j);
  1921.             yf += yfact;
  1922.             ye = (UWORD)yf;
  1923.             bf = yf - ye;
  1924.             if (ys > 0) {
  1925.                 tinr = inr + ((ys-1) * w);
  1926.                 ting = ing + ((ys-1) * w);
  1927.                 tinb = inb + ((ys-1) * w);
  1928.             }
  1929.             else {
  1930.                 tinr = inr + (ys * w);
  1931.                 ting = ing + (ys * w);
  1932.                 tinb = inb + (ys * w);
  1933.             }
  1934.  
  1935.             for (i=1; i<x; i++) {
  1936.                 newfr=0.0;
  1937.                 newfg=0.0;
  1938.                 newfb=0.0;
  1939.                 xf += xfact;
  1940.                 xe = (UWORD)xf;
  1941.                 tintr = tinr;
  1942.                 tintg = ting;
  1943.                 tintb = tinb;
  1944.  
  1945.                 if (xs == xe) {
  1946.                     if (ys > 0) {
  1947.                         newfr += tintr[xs] * tf;
  1948.                         tintr += w;
  1949.                         newfg += tintg[xs] * tf;
  1950.                         tintg += w;
  1951.                         newfb += tintb[xs] * tf;
  1952.                         tintb += w;
  1953.                     }
  1954.                     for (l = ys; l < ye; l++) {
  1955.                         newfr += tintr[xs];
  1956.                         tintr += w;
  1957.                         newfg += tintg[xs];
  1958.                         tintg += w;
  1959.                         newfb += tintb[xs];
  1960.                         tintb += w;
  1961.                     }
  1962.                     if (ye < h) {
  1963.                         newfr += tintr[xs] * bf;
  1964.                         newfg += tintg[xs] * bf;
  1965.                         newfb += tintb[xs] * bf;
  1966.                     }
  1967.                     *opr++ = newfr/yfact;
  1968.                     *opg++ = newfg/yfact;
  1969.                     *opb++ = newfb/yfact;
  1970.                 }
  1971.                 else {
  1972.                     float lf,rf;
  1973.  
  1974.                     rf = xf - floor(xf);
  1975.                     lf = xfact - rf;
  1976.                     if (ys > 0) {
  1977.                         newfr += ((tintr[xs] * lf) + (tintr[xe] * rf)) * tf;
  1978.                         tintr += w;
  1979.                         newfg += ((tintg[xs] * lf) + (tintg[xe] * rf)) * tf;
  1980.                         tintg += w;
  1981.                         newfb += ((tintb[xs] * lf) + (tintb[xe] * rf)) * tf;
  1982.                         tintb += w;
  1983.                     }
  1984.                     for (l = ys; l < ye; l++) {
  1985.                         newfr += ((tintr[xs] * lf) + (tintr[xe] * rf));
  1986.                         tintr += w;
  1987.                         newfg += ((tintg[xs] * lf) + (tintg[xe] * rf));
  1988.                         tintg += w;
  1989.                         newfb += ((tintb[xs] * lf) + (tintb[xe] * rf));
  1990.                         tintb += w;
  1991.                     }
  1992.                     if (ye < h) {
  1993.                         newfr += ((tintr[xs] * lf) + (tintr[xe] * rf)) * bf;
  1994.                         newfg += ((tintg[xs] * lf) + (tintg[xe] * rf)) * bf;
  1995.                         newfb += ((tintb[xs] * lf) + (tintb[xe] * rf)) * bf;
  1996.                     }
  1997.                     *opr++ = newfr/divf;
  1998.                     *opg++ = newfg/divf;
  1999.                     *opb++ = newfb/divf;
  2000.                     xs = xe;
  2001.                 }
  2002.             }
  2003.             tintr = tinr;
  2004.             newfr = 0.0;
  2005.             tintg = ting;
  2006.             newfg = 0.0;
  2007.             tintb = tinb;
  2008.             newfb = 0.0;
  2009.             if (ys > 0) {
  2010.                 newfr += tintr[w-1] * tf;
  2011.                 tintr += w;
  2012.                 newfg += tintg[w-1] * tf;
  2013.                 tintg += w;
  2014.                 newfb += tintb[w-1] * tf;
  2015.                 tintb += w;
  2016.             }
  2017.             for (l = ys; l < ye; l++) {
  2018.                 newfr += tintr[w-1];
  2019.                 tintr += w;
  2020.                 newfg += tintg[w-1];
  2021.                 tintg += w;
  2022.                 newfb += tintb[w-1];
  2023.                 tintb += w;
  2024.             }
  2025.             if (ye < h) {
  2026.                 newfr += tintr[w-1] * bf;
  2027.                 newfg += tintg[w-1] * bf;
  2028.                 newfb += tintb[w-1] * bf;
  2029.             }
  2030.             *opr++ = newfr/yfact;
  2031.             *opg++ = newfg/yfact;
  2032.             *opb++ = newfb/yfact;
  2033.             ys = ye + 1;
  2034.             tf = ys - yf;
  2035.         }
  2036.         SmoothX(tr,outr,w,x,y);
  2037.         SmoothX(tg,outg,w,x,y);
  2038.         SmoothX(tb,outb,w,x,y);
  2039.         return;
  2040.     }
  2041. }
  2042.